package com.flyqiu.flow.core.script;

import com.flyqiu.flow.api.script.*;
import de.odysseus.el.ExpressionFactoryImpl;
import de.odysseus.el.util.SimpleContext;

import javax.el.*;

public class DefaultJuelFlyQiuFlowScriptActuator implements FlyQiuFlowScriptActuator {
    public static final String JUEL_SCRIPT_TYPE = "juel";
    private static ExpressionFactory factory = null;

    protected CompositeELResolver defaultElResolver;
    private SimpleContext simpleContext;

    public DefaultJuelFlyQiuFlowScriptActuator() {
        initJuel();
    }

    private void initJuel() {
        simpleContext = new SimpleContext();
        factory = new ExpressionFactoryImpl();
        defaultElResolver = createDefaultElResolver();
    }

    protected CompositeELResolver createDefaultElResolver() {
        defaultElResolver = new CompositeELResolver();
        defaultElResolver.add(new ArrayELResolver());
        defaultElResolver.add(new ListELResolver());
        defaultElResolver.add(new MapELResolver());
        defaultElResolver.add(new JSONArrayElResolver());
        defaultElResolver.add(new JSONObjectElResolver());
        defaultElResolver.add(new BeanELResolver());
        return defaultElResolver;
    }


    /**
     * 脚本类型
     *
     * @return
     */
    @Override
    public String scriptType() {
        return JUEL_SCRIPT_TYPE;
    }

    protected CompositeELResolver createElResolver(IVariableScope scope) {
        CompositeELResolver compositeElResolver = new CompositeELResolver();
        compositeElResolver.add(new ProcJuelVariableResolver(scope));
        compositeElResolver.add(defaultElResolver);
        return compositeElResolver;
    }

    @Override
    public Object actuatorResult(String script, IVariableScope scope) {
        CompositeELResolver elResolver = createElResolver(scope);
        simpleContext.setELResolver(elResolver);
        ValueExpression valueExpression = factory.createValueExpression(simpleContext, script, Object.class);
        return valueExpression.getValue(simpleContext);
    }
}
